#include "../logs/lyzlog.h"
#include <thread>
#include <chrono>

void bench(const std::string &logger_name, size_t thr_count, size_t msg_count, size_t msg_len)
{
    // 1.获取日志器
    lyzlog::Logger::ptr logger = lyzlog::getLogger(logger_name);
    if (logger.get() == nullptr)
        return;

    std::cout << "测试日志: " << msg_count << "条， 总大小" << (msg_count * msg_len) / 1024 << "KB\n";

    // 2.组织指定长度字符串
    std::string msg(msg_len - 1, 'A');
    // 3.创建指定数量线程
    std::vector<std::thread> threads;
    std::vector<double> cost_arr(thr_count);
    size_t msg_per_thr = msg_count / thr_count;
    for (int i = 0; i < thr_count; i++)
    {
        threads.emplace_back([&, i]()
                             {
            //4.线程函数内部开始计时
            auto start = std::chrono::high_resolution_clock::now();
            //5.开始循环写日志
            for(int j = 0;j < msg_per_thr;j++)
            {
                logger->fatal("%s",msg.c_str());
            }
            //6.线程内部结束计时
            auto end = std::chrono::high_resolution_clock::now();
            std::chrono::duration<double> cost = end - start;
            cost_arr[i] = cost.count();
            std::cout << "线程" << i << ": "<<"\t输出数量：" << msg_count << ", 耗时：" << cost.count() << "s" << std::endl; });
    }
    
    for(auto &thr : threads) {
        thr.join();
    }
    // 7.计算总耗时间
    double max_count = cost_arr[0];
    for (auto e : cost_arr)
    {
        max_count = std::max(max_count, e);
    }
    size_t msg_per_sec = msg_count / max_count;
    size_t size_per_sec = (msg_count * msg_len) / (max_count * 1024);
    // 8.进行输出打印
    std::cout << "每秒输出日志数量：" << msg_per_sec << "条\n";
    std::cout << "每秒输出日志大小：" << size_per_sec << "KB\n";
}

void Sync_bench()
{
    std::unique_ptr<lyzlog::LoggerBuilder> builder(new lyzlog::GlobalLoggerBuilder);
    builder->BuilderFormatter("%m%n");
    builder->BuilderLogName("lyz-Synclog");
    builder->BuilderType(lyzlog::LoggerType::Sync_log);
    builder->BuilderLimitLev(lyzlog::Loglevel::value::DEBUG);
    builder->BuilderSink<lyzlog::FileSink>("./logfile/Syncfile.log");
    builder->Build();
    bench("lyz-Synclog", 1, 1000000, 100);
}

void Async_bench()
{
    std::unique_ptr<lyzlog::LoggerBuilder> builder(new lyzlog::GlobalLoggerBuilder);
    builder->BuilderFormatter("%m%n");
    builder->BuilderLogName("lyz-Asynclog");
    builder->BuilderType(lyzlog::LoggerType::Async_log);
    builder->BuilderLimitLev(lyzlog::Loglevel::value::DEBUG);
    builder->BuilderSink<lyzlog::FileSink>("./logfile/Asyncfile.log");
    builder->Build();
    bench("lyz-Asynclog", 4, 1000000, 100);
}

int main()
{
    //Sync_bench();
    Async_bench();
    return 0;
}